module nazo.savedata;
/**
 * value=data形式の保存データ
 * License: Public Domain
 */
import nazo.string, std.stdio, nazo.file, std.date, std.contracts, nazo.array, nazo.serialize;

/+static this(){
  SaveData test=new SaveData("test.txt");
  writefln(test.getValue("test"));
  writefln(test.getValue("test2"));
  writefln(test.getValue("test3"));
  test.removeAll();
  test.setValue("test","test_val");
  test.setValue("test2","Failed");
  test.setValue("test2","test2_val");
  test.setValue("test3","test3_val");
  test.removeValue("test3");
  test.flash();
}+/

class SaveData{
  //名前
  private string name;
  //内容
  private string[string] contents;
  ///リスト取得
  string[string] getList(){
    return contents;
  }
  ///値の設定
  void setValue(string name,string value){
    contents[name]=value;
  }
  ///値の取得
  string getValue(string name){
    auto t=name in contents;
    if(!t)return "";
    return *t;
  }
  ///値の削除
  void removeValue(string name){
    contents.remove(name);
  }
  ///全て削除
  void removeAll(){
    contents=null;
  }
  ///保存
  void flash(){
    if(contents==null){
      if(exists(name)&&isfile(name))
        std.file.remove(name);
      return;
    }
/*    string l;
    foreach(string name,string val;contents){
      l~=name~"="~val~"\n";
    }
    std.file.write(name,l);*/
    ubyte[] l = cast(ubyte[])\0"1.0";
    l~=multiserialize(contents);
    std.file.write(name, l);
  }
  ///更新日時
  d_time lastModified(){
    return getLastWriteTime(name);
  }
  ///ファイルが存在するか
  bool isExist(){
    if(exists(name) && isfile(name))
      return true;
    return false;
  }
  ///コンストラクタ
  this(string fileName){
    this.name=fileName;
    if(!isExist())return;
    ubyte[] l = cast(ubyte[]).read(this.name);
    if(l.length<4 || l[0..4]!=cast(ubyte[])\0"1.0"){
      string t=cast(string)l;
      t = t.replace("\r","").replace("\n\n","\n");///FIXME: 高速化
      if(t.length>0&&t[0]=='\n')
        t=t[1..$];
      if(t.length>0&&t[$-1] == '\n')
        t=t[0..$-1];
      getBefores(t,'\n',delegate void(string str){
        uint s=str.find('=');
        contents[str[0..s]]=str[s+1..$];
      });
      return;
    }

    multideserialize(l[4..$], contents);
  }
}

//alias ProcFile!(SaveData) TSaveData;

class TSaveData(string filename):SaveData{
  public{
    ///ファイル名の取得
    static string getFileName(){
      return filename;
    }
    ///コンストラクタ
    this(){
      super(getFileName());
    }
  }
}

class TSaveData(string filenamebefore, string filenameafter):SaveData{
  public{
    ///ファイル名の取得
    static string getFileName(string name){
      return filenamebefore~name~filenameafter; 
    }
    ///コンストラクタ
    this(string name){
      super(getFileName(name));
    }
  }
}
